<?php
/**
 *      [迷你云] (C)2009-2012 南京恒为网络科技.
 *   软件仅供研究与学习使用，如需商用，请访问www.miniyun.cn获得授权
 * 
 */
?>
<?php

class Move extends CApiComponent
{
        private $_action = 2;
    private $_userNick;
    public $toId;            public $fromId;          public $fromPath;       public $toPath;         public $from;
    public $toParent;
    public $target;
    
    public function __construct ()
    {
        parent::init();
        $this->result = array();
        $this->result["state"] = false;
        $this->result["code"] = 0;
        $this->result["msg"] = "移动失败";
        $this->result["data"] = array();
    }
    
    private function initById ()
    {
                if ($this->toId == 0) {
            $toParent = new UserFile();
            $toParent["id"] = 0;
            $toParent["file_path"] = "/{$this->_userId}";
        } else {
            $toParent = UserFile::model()->findByPk($this->toId);
        }
                $from = UserFile::model()->findByPk($this->fromId, "is_deleted=0");
        if (is_null($from) || is_null($toParent)) {
            throw new ApiException("Not found");
        }
        $this->fromPath = $from["file_path"];
        $pathInfo = CUtils::pathinfo_utf($this->fromPath);
        $this->toPath = $toParent['file_path'] . "/" . $pathInfo["basename"];
        $this->fromPath = CUtils::convertStandardPath($this->fromPath);
        $this->toPath = CUtils::convertStandardPath($this->toPath);
        $this->from = $from;
        $this->toParent = $toParent;
    }
    
    private function initByPath ()
    {
                $pathInfo = CUtils::pathinfo_utf($this->toPath);
        $dirname = $pathInfo["dirname"];
        if ($dirname == "/{$this->_userId}") {
            $toParent = $toParent = new UserFile();
            $toParent["id"] = 0;
            $toParent["file_path"] = "/{$this->_userId}";
        } else {
            $toParent = UserFile::model()->findByAttributes(
            array("file_path" => $dirname));
        }
                $from = UserFile::model()->findByAttributes(
        array("file_path" => $this->fromPath, "is_deleted" => 0));
        if (is_null($from))
            throw new ApiException("Not found");
        $this->from = $from;
        $this->toParent = $toParent;
    }
    
    public function invoke ($isPath = true)
    {
                $device = new UserDevice();
        $device = $device->findByUserIdAndType($this->_userId, 1);
        $this->_deviceId = $device["id"];
        $user = User::model()->findByPk($this->_userId);
        $this->_userNick = $user["user_name"];
        
                                $this->handleSpace();
        
        if ($isPath) {
            $this->fromPath = CUtils::convertStandardPath($this->fromPath);
            $this->toPath = CUtils::convertStandardPath($this->toPath);
            $this->initByPath();
        } else {
            $this->initById();
        }
        
                                if ($this->fromPath === $this->toPath) {
            $this->handleResult(false, 0, "已存在同名的文件");
            return;
        }
                                if (strpos($this->toPath, $this->fromPath . "/") === 0) {
            $this->result["msg"] = "不能移动到子目录";
            return;
        }
        
        if ($this->toPath == "/{$this->_userId}" ||
         $this->toPath == "/{$this->_userId}/") {
            $this->result["msg"] = "目标目录不存在";
            return;
        }
                                if (CUtils::checkNameInvalid($this->toPath) != 0 || CUtils::checkNameInvalid($this->toPath) != 0) {
             $this->result["msg"] = "命名不能包含下列字符串： ^|?*\\<\":>";
             return;
        }
        
                                $target = UserFile::model()->findByAttributes(array("user_id"=> $this->_userId, 
                                                             "file_path"=>$this->toPath, "is_deleted" => 0));
        if ($target) {
            $this->handleResult(false, 0, "已存在同名的文件");
            return;
        }
        
                if ($this->from["file_type"] == 0) {
            $this->handleMoveFile($this->fromPath, $this->toPath);
        } else {             $this->handleMoveFolder($this->fromPath, $this->toPath);
        }
        
        $this->handleResult(true, 0, "操作成功");
        $this->result["data"][$this->fromId]["state"] = true;
    }
    
    
    private function handleMoveFolder($fromPath, $toPath) {
        $createFolder = new CreateFolder();
        $createFolder->_deviceId = $this->_deviceId;
        $createFolder->_userId   = $this->_userId;
        $pathInfo = CUtils::pathinfo_utf($this->toPath);
        $parentId  = $createFolder->handleCreateByPath($pathInfo["dirname"]);
        
                $name = $this->handleRename($parentId, $pathInfo["basename"]);
        $this->toPath = $pathInfo["dirname"] . "/" .$name;
        
                                $deleted = UserFile::model()->findByAttributes(array("user_id"=> $this->_userId, "file_path"=>$this->toPath, "is_deleted" => 1));
        
        
                $children = new UserFile();
        $children = $children->getChildrenFileByPath($this->fromPath);
        foreach ($children as $child) {
            $filePath = $child["file_path"];
            $index    = strlen($this->fromPath);
            $filePath = substr_replace($filePath,$this->toPath, 0, $index);
            $action = 3;             if ($child["is_deleted"]) $action = 1;             $this->handleFileMeta($filePath, $child["version_id"], $this->_userId, $this->_userNick, $action);
        }
        
        $handler = new UserFile();
        if ($deleted) {
            $handler->updateAll(array('parent_file_id' => $this->from['id']), 
                                array('condition' => 'user_id=:user_id and parent_file_id=:parent_file_id',
                                      'params'    => array(':user_id'=>$this->_userId, ":parent_file_id" => $deleted["id"])));
            $deleted->delete();
        }
                $handler->updateAllByParentPath($this->fromPath, $this->toPath, $this->_userId);
        $this->from["file_path"]      = $this->toPath;
        $this->from["file_name"]      = $name;
        $this->from["event_uuid"]     = CUtils::random_string(46);
        $this->from["parent_file_id"] = $parentId;
        $this->from->save();
                $event = new UserEvent();
        $event->CreateEvent($this->_userId, $this->_deviceId, $this->_action, $this->fromPath, $this->toPath, $this->from["event_uuid"]);
    }
    
    
    private function handleMoveFile($fromPath, $toPath) {
        $createFolder = new CreateFolder();
        $createFolder->_deviceId = $this->_deviceId;
        $createFolder->_userId   = $this->_userId;
        $pathInfo = CUtils::pathinfo_utf($this->toPath);
        $parentId  = $createFolder->handleCreateByPath($pathInfo["dirname"]);
                $name = $this->handleRename($parentId, $pathInfo["basename"]);
        $this->toPath = $pathInfo["dirname"] . "/" .$name;
                                $deleted = UserFile::model()->findByAttributes(array("user_id"=> $this->_userId, "file_path"=>$this->toPath, "is_deleted" => 1));
        if ($deleted) $deleted->delete();
        
                $this->from["file_path"] = $this->toPath;
        $this->from["file_name"] = $name;
        $this->from["event_uuid"] = CUtils::random_string(46);
        $this->from["parent_file_id"] = $parentId;
        $this->from->save();
                $this->handleFileMeta($this->toPath, $this->from["version_id"], $this->_userId, $this->_userNick, 3);
                $event = new UserEvent();
        $event->CreateEvent($this->_userId, $this->_deviceId, $this->_action, $this->fromPath, $this->toPath, $this->from["event_uuid"]);
    }
    
    
    
    
    public function handleFileMeta($filePath, $versionId, $userId, $userNick, $action) {
                                $handler = new FileMeta();
        $meta = $handler->getFileMeta($filePath, "version");
        if ($meta) {
            $value = CUtils::getFileVersions($versionId, $action, $userId, $userNick, $meta["meta_value"]);
            $meta["meta_value"] = $value;
        } else {
            $meta = new FileMeta();
            $value = CUtils::getFileVersions($versionId, $action, $userId, $userNick);
            $meta["file_path"]  = $filePath;
            $meta["meta_key"]   = "version";
            $meta["meta_value"] = $value;
        }
        return $meta->save();
    }
    
    
    private function handleRename($parentId, $name) {
        $children = UserFile::model()->findAllByAttributes(array("parent_file_id" => $parentId, "user_id" => $this->_userId, "is_deleted" => 0));
        $names = array();
        foreach ($children as $child) {
            $names[$child["file_name"]] = $child["file_name"];
        }
                $name = CUtils::getConflictName($name, $names);
        return $name;
    }
    
    
    public function handleException ($exception)
    {
        echo CJSON::encode($this->result);
        Yii::app()->end();
    }
    
    
    public function handleError($code, $message, $file, $line) {
        echo CJSON::encode($this->result);
        Yii::app()->end();
    }
}
?>